/*************************************************************************
 *
 *   file		: FormatProvider.cs
 *   copyright		: (C) The WCell Team
 *   email		: info@wcell.org
 *   last changed	: $LastChangedDate: 2008-01-31 11:35:36 +0000 (Thu, 31 Jan 2008) $
 *   last author	: $LastChangedBy: tobz $
 *   revision		: $Rev: 87 $
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *************************************************************************/

using System.Text;

namespace DynamicMethods
{
    public interface IFormatProvider
    {
        string Int32ToHex(int int32);
        string Int16ToHex(int int16);
        string Int8ToHex(int int8);
        string Argument(int ordinal);
        string EscapedString(string str);
        string Label(int offset);
        string MultipleLabels(int[] offsets);
        string SigByteArrayToString(byte[] sig);
    }

    public class DefaultFormatProvider : IFormatProvider
    {
        public static DefaultFormatProvider Instance = new DefaultFormatProvider();

        private DefaultFormatProvider()
        {
        }

        #region IFormatProvider Members

        public virtual string Int32ToHex(int int32)
        {
            return int32.ToString("X8");
        }

        public virtual string Int16ToHex(int int16)
        {
            return int16.ToString("X4");
        }

        public virtual string Int8ToHex(int int8)
        {
            return int8.ToString("X2");
        }

        public virtual string Argument(int ordinal)
        {
            return string.Format("V_{0}", ordinal);
        }

        public virtual string Label(int offset)
        {
            return string.Format("IL_{0:x4}", offset);
        }

        public virtual string MultipleLabels(int[] offsets)
        {
            StringBuilder sb = new StringBuilder();
            int length = offsets.Length;
            for (int i = 0; i < length; i++)
            {
                if (i == 0) sb.AppendFormat("(");
                else sb.AppendFormat(", ");
                sb.Append(Label(offsets[i]));
            }
            sb.AppendFormat(")");
            return sb.ToString();
        }

        public virtual string EscapedString(string str)
        {
            int length = str.Length;
            StringBuilder sb = new StringBuilder(length*2);
            for (int i = 0; i < length; i++)
            {
                char ch = str[i];
                if (ch == '\t') sb.Append("\\t");
                else if (ch == '\n') sb.Append("\\n");
                else if (ch == '\r') sb.Append("\\r");
                else if (ch == '\"') sb.Append("\\\"");
                else if (ch == '\\') sb.Append("\\");
                else if (ch < 0x20 || ch >= 0x7f) sb.AppendFormat("\\u{0:x4}", (int) ch);
                else sb.Append(ch);
            }
            return "\"" + sb.ToString() + "\"";
        }

        public virtual string SigByteArrayToString(byte[] sig)
        {
            StringBuilder sb = new StringBuilder();
            int length = sig.Length;
            for (int i = 0; i < length; i++)
            {
                if (i == 0) sb.AppendFormat("SIG [");
                else sb.AppendFormat(" ");
                sb.Append(Int8ToHex(sig[i]));
            }
            sb.AppendFormat("]");
            return sb.ToString();
        }

        #endregion
    }
}